﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using Windows.Devices.Geolocation;
using HappyTravelling.DataModel;
using HappyTravelling.GeocodeService;
using HappyTravelling.Resources;
using HappyTravelling.ThanhService;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Maps.Controls;
using Microsoft.Phone.Shell;
using Newtonsoft.Json;
using Telerik.Windows.Controls;
using System.Device.Location;
using GestureEventArgs = System.Windows.Input.GestureEventArgs;
using MapLayer = Microsoft.Phone.Maps.Controls.MapLayer;
using Polygon = System.Windows.Shapes.Polygon;
using Rectangle = System.Windows.Shapes.Rectangle;

namespace HappyTravelling.Views
{
    public partial class AddDating : PhoneApplicationPage
    {

        Geolocator geolocator = null;
        bool tracking = false;
        ProgressIndicator pi;
        MapLayer PushpinMapLayer;
        private bool isMenuOpen = false;
        private Point menuPos;

        private readonly GeocodeServiceClient _svc;
        private ApplicationBar addBar, nextBar;
        private ApplicationBarIconButton bt1, bt2, bt3, bt4;
        private DatingModel NewDating;
        private List<User> _listFriendToAdd = new List<User>();
        private WebService1SoapClient client;
        private int meetingId;

        public AddDating()
        {
            InitializeComponent();
            client = new WebService1SoapClient();
            CreateApplicationBarButtons();
            pi = new ProgressIndicator();
            pi.IsIndeterminate = true;
            pi.IsVisible = false;
            try
            {
                _svc = new GeocodeServiceClient();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            _svc.GeocodeCompleted += (s, e) =>
            {
                // sort the returned record by ascending confidence in order for
                // highest confidence to be on the top. Based on the numeration High value is
                // at 0, Medium value at 1 and Low volue at 2
                GeocodeResult geoResult = (from r in e.Result.Results
                                           orderby (int)r.Confidence ascending
                                           select r).FirstOrDefault();
                if (geoResult != null)
                {
                    SetLocation(geoResult.Locations[0].Latitude,
                        geoResult.Locations[0].Longitude,
                        10,
                        true);
                }
            };
        }

        private void GetListFriend()
        {
            client.GetAllFriendsAsync(App.CurrentUser.Username);
            client.GetAllFriendsCompleted += client_GetAllFriendsCompleted;
        }

        private void client_GetAllFriendsCompleted(object sender, GetAllFriendsCompletedEventArgs e)
        {
            string json = e.Result;
            var ListFriends = JsonConvert.DeserializeObject<List<User>>(json);
            try
            {
                ListBoxFriend.ItemsSource = ListFriends;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
        private void SetLocation(double latitude, double longitude, double zoomLevel, bool showLocator)
        {
            // Move the pushpin to geo coordinate
            var location = new GeoCoordinate();
            location.Latitude = latitude;
            location.Longitude = longitude;

            ChoosingMap.SetView(location, zoomLevel);
            // Draw a pushpin
            DrawPushpin(location);

            // Show progress indicator while map resolves to new position
            pi.IsVisible = true;
            pi.IsIndeterminate = true;
            pi.Text = "Resolving...";
        }
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            //Creating a MapLayer and adding the MapOverlay to it
            PushpinMapLayer = new MapLayer();
            ChoosingMap.Layers.Add(PushpinMapLayer);
            GetListFriend();
            NewDating = new DatingModel();
            base.OnNavigatedTo(e);
        }
        private void CreateApplicationBarButtons()
        {
            addBar = new ApplicationBar();
            bt1 = new ApplicationBarIconButton
            {
                Text = AppResources.done,
                IconUri = new Uri("/Assets/AppBar/appbar.check.rest.png", UriKind.Relative)
            };
            bt1.Click += new EventHandler(btnAdd_Click);
            bt1.IsEnabled = true;
            addBar.Buttons.Add(bt1);

            bt2 = new ApplicationBarIconButton
            {
                Text = AppResources.cancel,
                IconUri = new Uri("/Assets/AppBar/appbar.cancel.rest.png", UriKind.Relative)
            };
            bt2.Click += new EventHandler(btnCancel_Click);
            addBar.Buttons.Add(bt2);

            nextBar = new ApplicationBar();
            nextBar.Opacity = 0.5;
            bt3 = new ApplicationBarIconButton
            {
                Text = AppResources.done,
                IconUri = new Uri("/Assets/AppBar/next.png", UriKind.Relative)
            };
            bt3.Click += new EventHandler(btnNext_Click);
            nextBar.Buttons.Add(bt3);

            bt4 = new ApplicationBarIconButton
            {
                Text = AppResources.cancel,
                IconUri = new Uri("/Assets/AppBar/appbar.cancel.rest.png", UriKind.Relative)
            };
            bt4.Click += new EventHandler(btnCancel_Click);
            nextBar.Buttons.Add(bt4);

            ApplicationBar = nextBar;
            ApplicationBar.Opacity = 0.5;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            DateTime dt = new DateTime(DatingTime.SelectedValue.Year, DatingTime.SelectedValue.Month,DatingTime.SelectedValue.Day,DatingTimer.SelectedValue.Hour,DatingTimer.SelectedValue.Minute,DatingTimer.SelectedValue.Second);
            client.CreateMeetingAsync(App.CurrentUser.id, tbName.Text + " tại " +TextAddress.Text,
                dt, ChoosingMap.Center.Latitude, ChoosingMap.Center.Longitude);
            client.CreateMeetingCompleted += client_CreateMeetingCompleted;
        }

        void client_CreateMeetingCompleted(object sender, CreateMeetingCompletedEventArgs e)
        {
            int addMeetingReturnCode = (int)e.Result;
            if (addMeetingReturnCode > 0)
            {
                MessageBox.Show("Tạo thành công");
                client.GetMeetingByIdAsync(addMeetingReturnCode);
                client.GetMeetingByIdCompleted += ClientOnGetMeetingByIdCompleted;
                
                NavigationService.GoBack();
            }
            else
            {
                MessageBox.Show("Nghẻo rồi");
            }
        }

        private void ClientOnGetMeetingByIdCompleted(object sender, GetMeetingByIdCompletedEventArgs e)
        {
            string json = e.Result;
            var meeting = JsonConvert.DeserializeObject<Meeting>(json);
            if (meeting != null)
            {
                meetingId = meeting.Id;
                Invite();
            }
        }

        private void Invite()
        {
            var ListChecked = ListBoxFriend.CheckedItems;
            foreach (var checkItem in ListChecked)
            {
                _listFriendToAdd.Add(new User { id = (checkItem as User).id });
            }
            ArrayOfInt arrayId = new ArrayOfInt();
            int k = 0;
            foreach (var friend in _listFriendToAdd)
            {
                arrayId.Add(friend.id);
               // arrayId[k] = friend.id;
            }
            client.InviteAsync(App.CurrentUser.id, arrayId ,meetingId);

        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            int index = MainPivot.SelectedIndex + 1;
            if (index < MainPivot.Items.Count)
                MainPivot.SelectedIndex = index;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            NavigationService.GoBack();
        }

        private void MainPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.Focus();
            tabControl1.PivotSelectedIndex = MainPivot.SelectedIndex;
            
            if (MainPivot.SelectedIndex == MainPivot.Items.Count - 1)
                ApplicationBar = addBar;
            else
                ApplicationBar = nextBar;
            if (MainPivot.SelectedIndex == 0)
                tbName.Focus();
            else if (MainPivot.SelectedIndex == 1)
            {
                NewDating.Name = tbName.Text;
            }
            else if (MainPivot.SelectedIndex == 2)
            {
                NewDating.Location = ChoosingMap.Center;
            }
            ApplicationBar.Opacity = 0.5;
        }

        private void StartDate_SelectedValueChanged(object sender, ValueChangedEventArgs<DateTime> args)
        {

        }

        private void btResult_Click(object sender, RoutedEventArgs e)
        {
            if (!tracking)
            {
                geolocator = new Geolocator();
                geolocator.DesiredAccuracy = PositionAccuracy.High;
                geolocator.MovementThreshold = 50; // The units are meters.
                geolocator.PositionChanged += geolocator_PositionChanged;
                tracking = true;
                btResult.Content = "stop tracking";
                this.ChoosingMap.ResolveCompleted += MapResolveCompleted;
            }
            else
            {
                geolocator.PositionChanged -= geolocator_PositionChanged;
                geolocator = null;
                tracking = false;
                btResult.Content = "track location";
                this.ChoosingMap.ResolveCompleted -= MapResolveCompleted;
            }
        }
        void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
        {
            Dispatcher.BeginInvoke(() =>
            {

                // Unfortunately, the Location API works with Windows.Devices.Geolocation.Geocoordinate objeccts
                // and the Maps controls use System.Device.Location.GeoCoordinate objects so we have to do a
                // conversion before we do anything with it on the map
                GeoCoordinate positionCoord = new GeoCoordinate()
                {
                    Altitude = args.Position.Coordinate.Altitude.HasValue ? args.Position.Coordinate.Altitude.Value : 0.0,
                    Course = args.Position.Coordinate.Heading.HasValue ? args.Position.Coordinate.Heading.Value : 0.0,
                    HorizontalAccuracy = args.Position.Coordinate.Accuracy,
                    Latitude = args.Position.Coordinate.Latitude,
                    Longitude = args.Position.Coordinate.Longitude,
                    Speed = args.Position.Coordinate.Speed.HasValue ? args.Position.Coordinate.Speed.Value : 0.0,
                    VerticalAccuracy = args.Position.Coordinate.AltitudeAccuracy.HasValue ? args.Position.Coordinate.AltitudeAccuracy.Value : 0.0
                };

                // Center the map on the new location
                this.ChoosingMap.Center = positionCoord;

                this.ChoosingMap.ZoomLevel = 15;

                //// Shorthand way of doing the above
                //GeoCoordinateEx gex = new GeoCoordinateEx();
                //gex = args.Position.Coordinate;
                //this.MyMap.Center = gex.GeoCoordinate;
                //// ... or using the Map extension method:
                //this.MyMap.SetCenter(args.Position.Coordinate);    


                // Draw a pushpin
                DrawPushpin(positionCoord);

                // Show progress indicator while map resolves to new position
                pi.IsVisible = true;
                pi.IsIndeterminate = true;
                pi.Text = "Resolving...";
                SystemTray.SetProgressIndicator(this, pi);
            });
        }

        private void MapResolveCompleted(object sender, MapResolveCompletedEventArgs e)
        {
            // Hide progress indicator
            pi.IsVisible = false;
            pi.IsIndeterminate = false;
            SystemTray.SetProgressIndicator(this, null);
        }

        private void DrawPushpin(GeoCoordinate coord)
        {
            var aPushpin = CreatePushpinObject();

            //Creating a MapOverlay and adding the Pushpin to it.
            MapOverlay MyOverlay = new MapOverlay();
            MyOverlay.Content = aPushpin;
            MyOverlay.GeoCoordinate = coord;
            MyOverlay.PositionOrigin = new Point(0, 0.5);

            // Add the MapOverlay containing the pushpin to the MapLayer
            this.PushpinMapLayer.Add(MyOverlay);
        }

        private Grid CreatePushpinObject()
        {
            //Creating a Grid element.
            Grid MyGrid = new Grid();
            MyGrid.RowDefinitions.Add(new RowDefinition());
            MyGrid.RowDefinitions.Add(new RowDefinition());
            MyGrid.Background = new SolidColorBrush(Colors.Transparent);

            //Creating a Rectangle
            Rectangle MyRectangle = new Rectangle();
            MyRectangle.Fill = new SolidColorBrush(Colors.Black);
            MyRectangle.Height = 20;
            MyRectangle.Width = 20;
            MyRectangle.SetValue(Grid.RowProperty, 0);
            MyRectangle.SetValue(Grid.ColumnProperty, 0);

            //Adding the Rectangle to the Grid
            MyGrid.Children.Add(MyRectangle);

            //Creating a Polygon
            Polygon MyPolygon = new Polygon();
            MyPolygon.Points.Add(new Point(2, 0));
            MyPolygon.Points.Add(new Point(22, 0));
            MyPolygon.Points.Add(new Point(2, 40));
            MyPolygon.Stroke = new SolidColorBrush(Colors.Black);
            MyPolygon.Fill = new SolidColorBrush(Colors.Black);
            MyPolygon.SetValue(Grid.RowProperty, 1);
            MyPolygon.SetValue(Grid.ColumnProperty, 0);

            //Adding the Polygon to the Grid
            MyGrid.Children.Add(MyPolygon);
            return MyGrid;
        }

        private void btSearch_Click(object sender, RoutedEventArgs e)
        {
            var request = new GeocodeRequest();

            // Only accept results with high confidence.
            request.Options = new GeocodeOptions
            {
                Filters = new ObservableCollection<FilterBase>
                {
                    new ConfidenceFilter
                    {
                        MinimumConfidence = Confidence.Low
                    }
                }
            };

            request.Credentials = new Credentials
            {
                ApplicationId = "AqLUxtORs5xCGuqdOfdXbMi9ul5TBUaBa-W_DIOQriW7MBhzTG-mqaktRU0qcA9O"
            };

            request.Query = TextAddress.Text;

            // Make asynchronous call to fetch the geo coordinate data.
            _svc.GeocodeAsync(request);
        }

        private void ListBoxFriend_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            
        }

        private void ChoosingMap_OnTap(object sender, GestureEventArgs e)
        {
            //var center = (GeoCoordinate)e;
            // Center the map on the new location
            //this.ChoosingMap.Center = new GeoCoordinate{Latitude = center.X, Longitude = center.Y};

            //this.ChoosingMap.ZoomLevel = 15;

            ////// Shorthand way of doing the above
            ////GeoCoordinateEx gex = new GeoCoordinateEx();
            ////gex = args.Position.Coordinate;
            ////this.MyMap.Center = gex.GeoCoordinate;
            ////// ... or using the Map extension method:
            ////this.MyMap.SetCenter(args.Position.Coordinate);    


            //// Draw a pushpin
            //DrawPushpin(new GeoCoordinate { Latitude = center.X, Longitude = center.Y });

        }

        private void StartTime_SelectedValueChanged(object sender, ValueChangedEventArgs<DateTime> args)
        {
            
        }
    }
}